package org.laizili.solution.leetcode;

import java.util.*;

/**
 * <a href="https://leetcode-cn.com/problems/mini-parser/">385. 迷你语法分析器</a>
 * <p>
 * tags: 栈;
 */
public class Problem385 {
    // This is the interface that allows for creating nested lists.
    // You should not implement it, or speculate about its implementation
    // 数据结构定义(防止报错)
    private static class NestedInteger {
        List<NestedInteger> list;
        Integer value;
        boolean isInteger;

        // Constructor initializes an empty nested list.
        public NestedInteger() {
            list = new ArrayList<>();
        }

        // Constructor initializes a single integer.
        public NestedInteger(int value) {
            isInteger = true;
            this.value = value;
        }

        // @return true if this NestedInteger holds a single integer, rather than a nested list.
        public boolean isInteger() {
            return isInteger;
        }

        // @return the single integer that this NestedInteger holds, if it holds a single integer
        // Return null if this NestedInteger holds a nested list
        public Integer getInteger() {
            return value;
        }

        // Set this NestedInteger to hold a single integer.
        public void setInteger(int value) {
            isInteger = true;
            this.value = value;
            list.clear();
        }

        // Set this NestedInteger to hold a nested list and adds a nested integer to it.
        public void add(NestedInteger ni) {
            isInteger = false;
            list.add(ni);
        }

        // @return the nested list that this NestedInteger holds, if it holds a nested list
        // Return empty list if this NestedInteger holds a single integer
        public List<NestedInteger> getList() {
            return isInteger ? Collections.singletonList(new NestedInteger(value)) : list;
        }

        @Override
        public String toString() {
            return isInteger ? value + "" : list.toString();
        }
    }

    private static class Solution {
        public NestedInteger deserialize(String s) {
            int length = s.length();
            int i = 0;
            Deque<NestedInteger> stack = new ArrayDeque<>();
            while (i < length) {
                char ch = s.charAt(i);
                if (Character.isDigit(ch) || '-' == ch) {
                    int digitEndIndex = i + 1;
                    while (digitEndIndex < length && Character.isDigit(s.charAt(digitEndIndex))) {
                        digitEndIndex++;
                    }
                    NestedInteger num = new NestedInteger(Integer.parseInt(s.substring(i, digitEndIndex)));
                    if (!stack.isEmpty()) {
                        stack.peek().add(num);
                    } else {
                        stack.push(num);
                    }
                    i = digitEndIndex;
                } else if ('[' == ch) {
                    stack.push(new NestedInteger());
                    i++;
                } else if (']' == ch) {
                    if (stack.size() > 1) {
                        NestedInteger top = stack.pop();
                        stack.peek().add(top);
                    }
                    i++;
                } else if (',' == ch) {
                    i++;
                }
            }
            return stack.peek();
        }

        public static void main(String[] args) {
            // TEST CASE
            System.out.println(new Solution().deserialize("123"));
            System.out.println(new Solution().deserialize("-123"));
            System.out.println(new Solution().deserialize("[123]"));
            System.out.println(new Solution().deserialize("[123,-123]"));
            System.out.println(new Solution().deserialize("[]"));
            System.out.println(new Solution().deserialize("[-1,2,3,-9,[],[13]]"));
        }
    }
}
